<!DOCTYPE html>
<html>
  <head>
    <title>testD3_chp14_1.html</title>
    
    <script type="text/javascript" src="https://d3js.org/d3.v5.min.js">
	</script>
	
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=GBK">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <svg width="960" height="600"></svg>
    <script>
    	var marge = {top:30,bottom:30,left:30,right:30}
    	var svg = d3.select("svg")
    	var width = svg.attr("width")
    	var height = svg.attr("height")
    	var g = svg.append("g")
    		.attr("transform","translate("+marge.top+","+marge.left+")");
    		
    	//准备数据
    	var nodes = [
    		{name:"g1"},
    		{name:"g2"},
    		{name:"g3"},
    		{name:"g4"},
    		{name:"g5"},
    		{name:"g6"},
    		{name:"g7"},
    		{name:"g8"},
    		{name:"g9"}
    	];
    	
    	var edges = [
    		{source:0,target:4,value:2}, //relation:"1"
    		{source:4,target:5,value:2},
    		{source:4,target:6,value:2},
    		{source:4,target:7,value:2},
    		{source:1,target:6,value:2},
    		{source:2,target:5,value:2},
    		{source:3,target:7,value:2},
    		{source:5,target:6,value:2},
    		{source:6,target:7,value:2},
    		{source:6,target:8,value:2}
    	];
    	//设置一个color的颜色比例尺，为了让不同的扇形呈现不同的颜色
    	var color = "steelblue";
	var link_color = "gray"
    	
    	//新建一个力导向图
    	var forceSimulation = d3.forceSimulation()
    		.force("link",d3.forceLink())
    		.force("charge",d3.forceManyBody())
    		.force("center",d3.forceCenter());;
    		
    	//初始化力导向图，也就是传入数据
    	//生成节点数据
    	forceSimulation.nodes(nodes)
    		.on("tick",ticked);//这个函数很重要，后面给出具体实现和说明
    	//生成边数据
    	forceSimulation.force("link")
    		.links(edges)
    		.distance(function(d){//每一边的长度
    			return d.value*100;
    		})    	
    	//设置图形的中心位置	
    	forceSimulation.force("center")
    		.x(width/2)
    		.y(height/2);
    	//在浏览器的控制台输出
    	console.log(nodes);
    	console.log(edges);
    	
    	//有了节点和边的数据后，我们开始绘制
    	//绘制边
    	var links = g.append("g")
    		.selectAll("line")
    		.data(edges)
    		.enter()
    		.append("line")
    		.attr("stroke",link_color)
    		.attr("stroke-width",2);
    	var linksText = g.append("g")
    		.selectAll("text")
    		.data(edges)
    		.enter()
    		.append("text")
    		.text(function(d){
    			return d.relation;
    		})
    	
    	//绘制节点
    	//老规矩，先为节点和节点上的文字分组
    	var gs = g.selectAll(".circleText")
    		.data(nodes)
    		.enter()
    		.append("g")
    		.attr("transform",function(d,i){
    			var cirX = d.x;
    			var cirY = d.y;
    			return "translate("+cirX+","+cirY+")";
    		})
    		.call(d3.drag()
    			.on("start",started)
    			.on("drag",dragged)
    			.on("end",ended)
    		);
    		
    	//绘制节点
    	gs.append("circle")
    		.attr("r",10)
    		.attr("fill",color)
    	//文字
    	gs.append("text")
    		.attr("x",-10)
    		.attr("y",-20)
    		.attr("dy",10)
    		.text(function(d){
    			return d.name;
    		})
    	
    	function ticked(){
    		links
    			.attr("x1",function(d){return d.source.x;})
    			.attr("y1",function(d){return d.source.y;})
    			.attr("x2",function(d){return d.target.x;})
    			.attr("y2",function(d){return d.target.y;});
    			
    		linksText
    			.attr("x",function(d){
    			return (d.source.x+d.target.x)/2;
    		})
    		.attr("y",function(d){
    			return (d.source.y+d.target.y)/2;
    		});
    			
    		gs
    			.attr("transform",function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    	}
    	function started(d){
    		if(!d3.event.active){
    			forceSimulation.alphaTarget(0.8).restart();
    		}
    		d.fx = d.x;
    		d.fy = d.y;
    	}
    	function dragged(d){
    		d.fx = d3.event.x;
    		d.fy = d3.event.y;
    	}
    	function ended(d){
    		if(!d3.event.active){
    			forceSimulation.alphaTarget(0);
    		}
    		d.fx = null;
    		d.fy = null;
    	}
    </script>
  </body>
</html>
